package team.seekers.hula.question.answer.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.common.entity.VisibilityUpdateDTO;
import team.seekers.hula.common.entity.enums.StatusEnum;
import team.seekers.hula.record.mind.service.MindService;
import team.seekers.hula.question.answer.entity.dao.AnswerDO;
import team.seekers.hula.question.answer.entity.dto.AnswerQueryDTO;
import team.seekers.hula.question.answer.entity.dto.AnswerUpdateManageDTO;
import team.seekers.hula.question.answer.entity.vo.AnswerListVO;
import team.seekers.hula.question.answer.entity.vo.AnswerManageListVO;
import team.seekers.hula.question.answer.mapper.AnswerMapper;
import team.seekers.hula.question.answerComment.service.AnswerCommentService;
import team.seekers.hula.question.point.entity.dao.PointDO;
import team.seekers.hula.question.point.service.PointService;
import team.seekers.hula.auth.service.MindUtils;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.user.user.entity.vo.UserBasicInfoVO;
import team.seekers.hula.user.user.service.UserService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 一个回答 服务实现类
 * </p>
 *
 * @author hbc
 * @since 2021-02-15
 */
@Service
public class AnswerManageService extends ServiceImpl<AnswerMapper, AnswerDO> {

    @Autowired
    @Lazy
    private UserService userService;

    @Autowired
    @Lazy
    private MindService mindService;

    @Autowired
    @Lazy
    private PointService pointService;
    @Autowired
    @Lazy
    private AnswerCommentService answerCommentService;
    @Autowired
    @Lazy
    private AnswerGoodService answerGoodService;



    public void delete(String answerId) {
        //删除回答下面所有的评论
        answerCommentService.deleteByAnswerId(answerId);

        //删除回答所有的赞
        answerGoodService.deleteByAnswerId(answerId);

        // 维护mind表
        mindService.deleteMindByLinkId(answerId);

        // 删除回答
        removeById(answerId);
    }

    public void deleteByPointId(String pointId) {

    }

    public void deleteByPointIds(ArrayList<String> pointIds) {

    }


    @Transactional(rollbackFor = Exception.class)
    public void update(AnswerUpdateManageDTO updateVO) {
        AnswerDO answerDO = getById(updateVO.getId());
        BeanUtils.copyProperties(updateVO, answerDO);
        updateById(answerDO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateVisibility(VisibilityUpdateDTO updateDTO) {
        lambdaUpdate().set(AnswerDO::getVisibility,updateDTO.getVisibility())
                .eq(AnswerDO::getId,updateDTO.getId())
                .update();

        mindService.updateVisibilityByLinkId(updateDTO.getId(),updateDTO.getVisibility());
    }





    public PageResult<AnswerManageListVO> adminPageOrderByTime(long current, long limit, AnswerQueryDTO answerQuery) {
        Page<AnswerQueryDTO> page = new Page<>(current,limit);
        IPage<AnswerManageListVO> list = baseMapper.pageAnswerCondition(page,answerQuery);
        List<AnswerManageListVO> records = list.getRecords();
        if(records == null)
            return null;
        long total = list.getTotal();

        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("rows",records);
        return new PageResult<>(total,records);
    }

    public List<AnswerManageListVO> getAllAdminAnswerInfo() {
        List<AnswerManageListVO> listAnswerVos = baseMapper.getAnswerInfo();
        return listAnswerVos;
    }


    //更新所有字段的heat值
    @Transactional(rollbackFor=Exception.class)
    public void updateAnswersHeatByPointId(String pointId){
        Date now=new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date currentDate = sdf.parse(sdf.format(now));
            QueryWrapper<AnswerDO> wrapper = new QueryWrapper<>();
            wrapper.eq("point_id",pointId);
            List<AnswerDO> answerDOList = baseMapper.selectList(wrapper);
            for(AnswerDO answerDO : answerDOList){
                String v = setAnswerHot(answerDO, currentDate);
                answerDO.setHeat(v);
                baseMapper.updateById(answerDO);
            }
        } catch (ParseException e){
            e.printStackTrace();
        }
    }

    //热度排行算法
    public String setAnswerHot(AnswerDO answerDO, Date currentDate) {
        Integer goodNumber = answerDO.getLikeCount();
        Integer commentNumber = answerDO.getCommentCount();
        Date gmtCreate = answerDO.getGmtCreate();
        float v = MindUtils.differentDaysByMillisecond(gmtCreate, currentDate);
        double heat = (goodNumber*3+commentNumber*5+1) / Math.pow((v + 2), 1.8);
        return heat+"";
    }

    public String addComment(String answerId) {
        AnswerDO answerDO = getById(answerId);
        answerDO.setCommentCount(answerDO.getCommentCount()+1);
        updateById(answerDO);
        return answerDO.getId();
    }

    public String addGood(String answerId) {
        AnswerDO answerDO = getById(answerId);
        answerDO.setLikeCount(answerDO.getLikeCount()+1);
        updateById(answerDO);
        return answerDO.getId();
    }

    public String reduceComment(String answerId) {
        AnswerDO answerDO = getById(answerId);
        answerDO.setCommentCount(answerDO.getCommentCount()-1);
        updateById(answerDO);
        return answerDO.getId();
    }

    public String reduceGood(String answerId) {
        AnswerDO answerDO = getById(answerId);
        answerDO.setLikeCount(answerDO.getLikeCount()-1);
        updateById(answerDO);
        return answerDO.getId();
    }

    public PageResult<AnswerListVO> page(AnswerQueryDTO answerQuery) {
        //首先更新热度
        updateAnswersHeatByPointId(answerQuery.getPointId());

        LambdaQueryChainWrapper<AnswerDO> wrapper = lambdaQuery().eq(AnswerDO::getPointId, answerQuery.getPointId());

        if(!StringUtils.isEmpty(answerQuery.getBegin())){
            wrapper.ge(AnswerDO::getGmtCreate,answerQuery.getBegin());
        }
        if (!StringUtils.isEmpty(answerQuery.getEnd())){
            wrapper.le(AnswerDO::getGmtCreate,answerQuery.getEnd());
        }

        switch (answerQuery.getOrderEnum()){
            case NEW:
                wrapper.orderByDesc(AnswerDO::getGmtCreate);
                break;
            case DEFAULT:
                wrapper.orderByDesc(AnswerDO::getHeat);
                break;
            case ME:
                wrapper.orderByDesc(AnswerDO::getHeat);
                wrapper.eq(AnswerDO::getUserId,MindUtils.getUserId());
                break;
        }

        Page<AnswerDO> page = wrapper.page(new Page<>(answerQuery.getPageNow(), answerQuery.getPageSize()));

        long total = page.getTotal();
        List<AnswerDO> records = page.getRecords();
        if(records == null){
            return null;
        }
        List<AnswerListVO> list = new ArrayList<>();
        for (AnswerDO record : records) {
            AnswerListVO answerListVO = new AnswerListVO();
            BeanUtils.copyProperties(record,answerListVO);
            UserDO userDO = userService.getById(record.getUserId());
            if(userDO == null){
                return null;
            }
            if(!record.getUserId().equals(MindUtils.getUserId())){
                answerListVO.setIsMine(true);
            }
            answerListVO.setUserId(userDO.getId());
            answerListVO.setNickname(userDO.getNickname());
            answerListVO.setAvatar(userDO.getAvatar());
            list.add(answerListVO);
        }
        return new PageResult<>(total,list);
    }

    public PageResult<AnswerManageListVO> listInManage(AnswerQueryDTO answerQueryDTO){
        QueryWrapper<AnswerDO> answerDOQueryWrapper = new QueryWrapper<>();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(answerQueryDTO.getNickname())){
            //如果用户名不为空，需要查询符合条件的userid
            List<UserDO> userDOS = userService.list(new QueryWrapper<UserDO>().like("nickname", answerQueryDTO.getNickname()));
            Set<String> userIds = new HashSet<>();
            for (UserDO userDO : userDOS) {
                userIds.add(userDO.getId());
            }
            if(userIds.size()!=0){
                answerDOQueryWrapper.in("user_id",userIds);
            }else{
                return new PageResult<>();
            }
        }


        if (org.apache.commons.lang3.StringUtils.isNotBlank(answerQueryDTO.getKeyword())){
            //如果观点名称不为空，需要查询符合条件的pointid
            List<PointDO> pointDOS = pointService.list(new QueryWrapper<PointDO>().like("keyword", answerQueryDTO.getKeyword()));
            Set<String> pointIds = new HashSet<>();
            for (PointDO pointDO : pointDOS) {
                pointIds.add(pointDO.getId());
            }
            if(pointIds.size()!=0){
                answerDOQueryWrapper.in("point_id",pointIds);
            }else{
                return new PageResult<>();
            }
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(answerQueryDTO.getContent())){
            answerDOQueryWrapper.like("content",answerQueryDTO.getContent());
        }

        if(!StringUtils.isEmpty(answerQueryDTO.getId())){
            answerDOQueryWrapper.like("id",answerQueryDTO.getId());
        }

        if(!StringUtils.isEmpty(answerQueryDTO.getQuestionId())){
            answerDOQueryWrapper.like("question_id",answerQueryDTO.getQuestionId());
        }

        if (answerQueryDTO.getStatus()!=null){
            answerDOQueryWrapper.eq("status",answerQueryDTO.getStatus());
        }


        Page<AnswerDO> page = page(new Page<>(answerQueryDTO.getPageNow(), answerQueryDTO.getPageSize()),answerDOQueryWrapper);

        ArrayList<AnswerManageListVO> answerManageListVOS = new ArrayList<>();
        for (AnswerDO record : page.getRecords()) {
            AnswerManageListVO answerManageListVO = new AnswerManageListVO();
            BeanUtils.copyProperties(record,answerManageListVO);

            UserBasicInfoVO basicInfoVO = userService.getBasicInfoVO(record.getUserId());
            answerManageListVO.setNickname(basicInfoVO.getNickname());
            answerManageListVO.setAvatar(basicInfoVO.getAvatar());

            answerManageListVO.setStatus(record.getStatus().getName());

            PointDO pointDO = pointService.getById(record.getPointId());
            answerManageListVO.setPointKey(pointDO.getKeyword());

            answerManageListVOS.add(answerManageListVO);
        }
        return new PageResult<>(page.getTotal(),answerManageListVOS);
    }
    public void changeApproval(String id,Integer status) {
        AnswerDO answerDO = getById(id);
        if (answerDO == null) {
            return;
        }
        //判断重复审批
        if (answerDO.getStatus().getType() == 1 || answerDO.getStatus().getType() == 2) {
            return;
        }
        answerDO.setStatus(StatusEnum.getByType(status));
        updateById(answerDO);

    }
}
